/**
 * Notes: 用户管理
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-01-22  07:48:00 
 */

const BaseProjectAdminService = require('./base_project_admin_service.js');

const util = require('../../../../framework/utils/util.js');
const exportUtil = require('../../../../framework/utils/export_util.js');
const timeUtil = require('../../../../framework/utils/time_util.js');
const dataUtil = require('../../../../framework/utils/data_util.js');
const LogModel = require('../../../../framework/platform/model/log_model.js');
const UserModel = require('../../model/user_model.js');
const AnswerModel = require('../../model/answer_model.js');
const AdminHomeService = require('./admin_home_service.js');

// 导出用户数据KEY
const EXPORT_USER_DATA_KEY = 'EXPORT_USER_DATA';

// 导出排行榜数据KEY
const EXPORT_RANK_DATA_KEY = 'EXPORT_RANK_DATA';

class AdminUserService extends BaseProjectAdminService {
	/** 获得某个用户信息 */
	async getUser({
		userId,
		fields = '*'
	}) {
		let where = {
			USER_MINI_OPENID: userId,
		}
		return await UserModel.getOne(where, fields);
	}

	/** 取得用户分页列表 */
	async getUserList({
		search, // 搜索条件
		sortType, // 搜索菜单
		sortVal, // 搜索菜单
		orderBy, // 排序
		whereEx, //附加查询条件 
		page,
		size,
		oldTotal = 0
	}) {
		orderBy = orderBy || {
			USER_ADD_TIME: 'desc'
		};
		let fields = '*';
		let where = {};
		where.and = {
			_pid: this.getProjectId() //复杂的查询在此处标注PID
		};

		if (util.isDefined(search) && search) {
			where.or = [{
				USER_NAME: ['like', search]
			},
			{
				USER_MOBILE: ['like', search]
			},
			{
				USER_MEMO: ['like', search]
			},
			];
		} else if (sortType && util.isDefined(sortVal)) {
			// 搜索菜单
			switch (sortType) {
				case 'status':
					where.and.USER_STATUS = Number(sortVal);
					break;
				case 'sort': {
					orderBy = this.fmtOrderBySort(sortVal, 'USER_ADD_TIME');
					break;
				}
			}
		}
		let result = await UserModel.getList(where, fields, orderBy, page, size, true, oldTotal, false);
		// 为导出增加一个参数condition
		result.condition = encodeURIComponent(JSON.stringify(where));
		return result;
	}

	async statusUser(id, status, reason) {
		// 检查用户是否存在
		const user = await UserModel.getOne({ 'USER_MINI_OPENID': id, _pid: this.getProjectId() });
		if (!user) {
			this.AppError('用户不存在');
		}

		// 验证状态值
		if (![UserModel.STATUS.UNUSE,
			 UserModel.STATUS.COMM, 
			 UserModel.STATUS.UNCHECK,
			  UserModel.STATUS.FORBID].includes(status)) {
			this.AppError('状态值必须为[0,1,8,9],当前设置为：' + status);
		}

		// 更新用户状态
		await UserModel.edit({'USER_MINI_OPENID':id}, {
			USER_STATUS: status,
			USER_CHECK_REASON: reason || '',
			USER_EDIT_TIME: timeUtil.time()
		});

		// 记录日志
		this.insertLog(`将用户[${user.USER_NAME}]状态修改为${status}`, this._admin, LogModel.TYPE.SYS);
		return { success: true };
	}

	/**删除用户 */
	async delUser(id) {
		// 检查用户是否存在
		const user = await UserModel.getOne({ 'USER_MINI_OPENID': id, _pid: this.getProjectId() });
		if (!user) {
			this.AppError('用户不存在');
		}
		await UserModel.del({ 'USER_MINI_OPENID': id });

		// 记录日志
		this.insertLog(`删除了用户[${user.USER_NAME}]`, this._admin, LogModel.TYPE.SYS);
		return { success: true };
	}

	// #####################导出用户数据

	/**获取用户数据 */
	async getUserDataURL() {
		return await exportUtil.getExportDataURL(EXPORT_USER_DATA_KEY);
	}

	/**删除用户数据 */
	async deleteUserDataExcel() {
		return await exportUtil.deleteDataExcel(EXPORT_USER_DATA_KEY);
	}

	/**导出用户数据 */
	async exportUserDataExcel(condition, fields) {
		// 解析查询条件
		const where = JSON.parse(decodeURIComponent(condition));
		where.and = { ...where.and, _pid: this.getProjectId() };

		// 定义Excel表头
		const header = [
			'用户ID', '昵称', '手机号', '状态', '注册时间', '最后登录时间',
			'答题次数', '正确次数', '错误次数', '正确率'
		];

		// 查询用户数据
		const users = await UserModel.getListAll(where, fields || '*');
		if (!users.length) {
			this.AppError('没有可导出的用户数据');
		}

		// 处理数据行
		const rows = [];
		for (const user of users) {
			// 查询用户答题统计
			const answerStats = await AnswerModel.stat({ USER_ID: user._id });

			rows.push([
				user._id,
				user.USER_NAME || '',
				user.USER_MOBILE || '',
				user.USER_STATUS === 1 ? '正常' : '禁用',
				timeUtil.timestamp2Time(user.USER_ADD_TIME),
				timeUtil.timestamp2Time(user.USER_LOGIN_TIME || 0),
				answerStats.total || 0,
				answerStats.correct || 0,
				answerStats.wrong || 0,
				answerStats.total ? ((answerStats.correct / answerStats.total) * 100).toFixed(2) + '%' : '0%'
			]);
		}

		// 生成Excel并上传
		return await exportUtil.exportExcel(EXPORT_USER_DATA_KEY, '用户数据_' + timeUtil.date('YmdHis'), header, rows);
	}


	// #####################导出排行榜数据

	/**获取用户数据 */
	async getRankDataURL() {
		return await exportUtil.getExportDataURL(EXPORT_RANK_DATA_KEY);
	}

	/**删除用户数据 */
	async deleteRankDataExcel() {
		return await exportUtil.deleteDataExcel(EXPORT_RANK_DATA_KEY);
	}

	/**导出用户数据 */
	async exportRankDataExcel() {
		// 获取排行榜数据
		const homeService = new AdminHomeService();
		const rankData = await homeService.getRankList({ size: 1000 });

		if (!rankData.list.length) {
			this.AppError('没有可导出的排行榜数据');
		}

		// 定义Excel表头
		const header = ['排名', '用户ID', '昵称', '答对题数', '答题总数', '正确率', '最后答题时间'];

		// 处理数据行
		const rows = [];
		rankData.list.forEach((item, index) => {
			rows.push([
				index + 1,
				item.USER_ID,
				item.USER_NAME || '',
				item.correct,
				item.total,
				item.rate ? (item.rate * 100).toFixed(2) + '%' : '0%',
				timeUtil.timestamp2Time(item.lastTime || 0)
			]);
		});

		// 生成Excel并上传
		return await exportUtil.exportExcel(EXPORT_RANK_DATA_KEY, '排行榜数据_' + timeUtil.date('YmdHis'), header, rows);
	}


}

module.exports = AdminUserService;